<?php

namespace App\Http\Controllers\Api\V1\Wechat;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Support\generate_sign;
use Illuminate\Support\Facades\DB;
use App\Models\UsersWechat;
use App\Models\Order;
use App\Models\Box;
use App\Models\EnergyCome;
use App\Models\BoxCare;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;
use Validator;
class WechatPayController extends Controller
{
    private  $options;
    private  $app;


    public function postCreateOrder(Request $request){
        $validator = Validator::make($request->all(),
            [
                'token'=> 'required|string',
                'type' => 'required|string',
                'id' => 'integer',
            ],[
                'required' => '字段 :attribute 不能为空.',
                'string' => '字段 :attribute 是字符型.',
                'integer'=>'字段 :attribute 是数字型.',
            ]);
        if ($validator->fails()) {
            $messages = $validator->errors();
            return response()->json(['code' => -1,'msg' => $messages->first(),'data' => '',]);
        }
        $input = $request->all();
        if ($user = $this->JwtChecking($request)) {
            $wechat_id = $user->id;
            $input['wechat_id'] = $user->id;
            $input['pay_type'] = 'wechat';
            $return = Order::add($input);
            if ($return['return_code']=='ERROR') {
                return response()->json(['code' => -1,'msg' => $return['msg'],'data' => null]);
            }
            $config = config('wechat.payment.default');
            $payment = Factory::Payment($config); // 微信支付
            $order = $return['data'];
            $result = $payment->order->unify([
                'body'         => $order->name,
                'out_trade_no' => $order->order_no,
                'trade_type'   => 'JSAPI',  // 必须为JSAPI
                'openid'       => $user->openid, // 这里的openid为付款人的openid
                'total_fee'    => $order->product_amount_total, // 总价
                'notify_url'   => config('services.domain').'api/v1/payments/wechat-notify',
            ]);

            // 如果成功生成统一下单的订单，那么进行二次签名
            if ($result['return_code'] === 'SUCCESS') {
                Order::where('id',$return['data']->id)->update(['prepay_id'=>$result['prepay_id']]);
                // return response()->json(['code' => 1,'msg' => 'Success','data' => $result]);
                // 二次签名的参数必须与下面相同
                $params = [
                    'appId'     => $config['app_id'],
                    'timeStamp' => time(),
                    'nonceStr'  => $result['nonce_str'],
                    'package'   => 'prepay_id=' . $result['prepay_id'],
                    'signType'  => 'MD5',
                ];
                $params['paySign'] = $this->generate_sign($params, config('wechat.payment.default.key'));
                return response()->json(['code' => 1,'msg' => 'Success','data' => $params]);
            } else {
                return response()->json(['code' => -1,'msg' => $result['return_msg'],'data' => null]);
            }
        }else{
             return response()->json(['code' => -401,'msg' => 'token_not_provided：token不存在','data' => '',]);
        }
    }


    public function generate_sign($data = [],$key){
        //签名步骤一：按字典序排序参数
        ksort($data);
        $buff = "";
        foreach ($data as $k => $v) {
            if ($k != "sign" && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        //签名步骤二：在string后加入KEY
        $string = $buff . "&key=" . $key;
        //签名步骤三：MD5加密
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        $sign = strtoupper($string);
        return $sign;
    }

    public function paynotify(Request $requset){
        $config = config('wechat.payment.default');
        $app = Factory::Payment($config);
        // //$message 为微信推送过来的通知信息，为一个数组；
        // //- $fail 为一个函数，触发该函数可向微信服务器返回对应的错误信息，微信会稍后重试再通知。
        $response = $app->handlePaidNotify(function($message, $fail){

            $return = order::Handle($message);
            if ($return) {
                return true; // 返回处理完成
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
        });
        return $response;
    }
}
